import 'package:easy_refresh/easy_refresh.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:im_app/im/page/sub/SessionGroupSettingPage.dart';
import 'package:im_app/im/page/sub/SessionUserSettingPage.dart';
import 'package:im_app/im/page/view/CaptureAudioView.dart';
import 'package:im_app/im/page/view/LoadingView.dart';
import 'package:im_app/im/page/view/MessageHandlerView.dart';
import 'package:im_app/im/page/view/MovableView.dart';
import 'package:im_app/im/page/view/component/cell/MessageItemView.dart';
import 'package:im_app/im/page/view/MessageSendCubitView.dart';
import 'package:im_app/im/service/ImGroupService.dart';
import 'package:im_app/im/util/ImCacheFactory.dart';
import 'package:im_app/im/util/ImConstant.dart';
import 'package:im_app/im/util/ImSingleton.dart';
import 'package:provider/provider.dart';
import 'package:super_sliver_list/super_sliver_list.dart';
import '../../data/StaticData.dart';
import '../pojo/Enums.dart';
import '../pojo/ImPojo.dart';
import '../service/ImSessionService.dart';
import '../util/LoggerUtil.dart';
import '../util/UiUtil.dart';
import 'bloc/MessageSendCubit.dart';
import 'bloc/MessageListCubit.dart';
import 'bloc/SessionListCubit.dart';
import 'bloc/SessionSettingCubit.dart';

// 消息展示+消息发送页面  通过bloc控制实现
class MessageSendPage0 extends StatelessWidget {
  const MessageSendPage0({super.key});

  @override
  Widget build(BuildContext context) {
    var arguments = ModalRoute.of(context)?.settings.arguments as Map;
    int sessionId = arguments['id'];
    String sessionName = arguments['name'];
    int? messageId = arguments['messageId'];

    var messageListCubit = MessageListCubit(sessionId: sessionId, messageId: messageId);
    return MultiBlocProvider(providers: [
      BlocProvider(
        create: (_) => messageListCubit,
      ),
      BlocProvider(
        create: (BuildContext context) => MessageSendCubit(messageListCubit: messageListCubit, sessionId: sessionId),
      )
    ], child: _MessageSendPageView(sessionId: sessionId, sessionName: sessionName));
  }
}

class _MessageSendPageView extends StatefulWidget {
  final int sessionId;
  final String sessionName;

  const _MessageSendPageView({required this.sessionId, required this.sessionName, super.key});

  @override
  State<StatefulWidget> createState() => _MessageSendPageState();
}

class _MessageSendPageState extends State<_MessageSendPageView> {
  late ListController _listController;
  late ScrollController _scrollController;
  bool isHaveScroll = false;  // 是否有滚动条
  bool isLoading = false;     // 是否正在加载数据

  final _logger = createLogger();

  @override
  void initState() {
    super.initState();

    _listController = ListController();
    _scrollController = ScrollController();

    final messageListCubit = context.read<MessageListCubit>();
    ImSingleton.getInstance().messageListCubit = messageListCubit;

    _scrollController.addListener(()=> _onScroll(messageListCubit));

    // messageListCubit.loadData();
    messageListCubit.add(MessageListLoadDataEvent());
    _logger.i("init state !!!!!!!!!!!!!!!!!!");
  }

  @override
  void dispose() {
    _listController.dispose();
    _scrollController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final messageListCubit = context.watch<MessageListCubit>();
    return BlocConsumer<MessageListCubit, MessageListState>(
        listener: (BuildContext context, MessageListState messageListState) {
          if (messageListState.forwardSession != null && messageListState.forwardUrl != null) {
            Navigator.of(context).popUntil(ModalRoute.withName("/MessageSendPage"));

            UiUtil.showSnackBar(context, messageListState.businessMsg);
            return;
          }
          if (messageListState.selectIndex >= 0 && messageListState.wrapMessages.isNotEmpty && messageListState
              .selectIndex < messageListState.wrapMessages.length) {
            _scroll(messageListState.selectIndex, messageListState.type == LoadingType.old);
            _logger.i("selectIndex: ${messageListState.selectIndex}, ${messageListState.wrapMessages.length}");
            // _scrollEnd(messageListState);
          } else {
            _logger.i("error selectIndex: ${messageListState.selectIndex}, ${messageListState.wrapMessages.length}");
          }
        }, builder: (BuildContext context, MessageListState state) {
      return Scaffold(
        appBar: _buildAppBar(context),
        backgroundColor: ImConstant.IM_MAIN_BACKGROUND_COLOR,
        body: _buildBody(messageListCubit),
      );
    });
  }

  Widget _buildBody(MessageListCubit messageListCubit) {
    return LoadingView(
      state: messageListCubit.state.state,
      child: Stack(
        children: [
          _buildMessagePane(messageListCubit),

          Visibility(
              visible: messageListCubit.state.isAudio,
              child: CaptureAudioView(sessionId: messageListCubit.sessionId))
        ],
      ),
    );
  }

  Widget _buildMessagePane(MessageListCubit messageListCubit) {
    return Column(
      children: [
        if (isHaveScroll)
          Expanded(child: GestureDetector(
              child: _buildMessageList(context),
              onTap: () {
                final messageSendCubit = context.read<MessageSendCubit>();
                messageSendCubit.hideEmoji();
              })
          ),
        if (!isHaveScroll)
          Expanded(child: MovableView(headMoveMaxHeight: 100, trailMoveMaxHeight: 150, backgroundColor: Colors.grey,
              widgetBuilder: (context)=>GestureDetector(
                  child: _buildMessageList(context),
                  onTap: () {
                    final messageSendCubit = context.read<MessageSendCubit>();
                    messageSendCubit.hideEmoji();
                  }))
          ),
        Container(
          decoration: BoxDecoration(
            color: Colors.grey.shade100,
          ),
          padding: const EdgeInsets.all(5),
          child: Padding(padding: const EdgeInsets.only(bottom: 10), child: _buildSendPane(messageListCubit),),
        )
      ],
    );
  }

  Widget _buildMessageList(BuildContext context) {
    var messageListCubit = context.read<MessageListCubit>();
    return SuperListView.builder(
      listController: _listController,
      controller: _scrollController,
      scrollDirection: Axis.vertical,
      physics: const AlwaysScrollableScrollPhysics(),
      // physics: const ClampingScrollPhysics(),
      itemCount: messageListCubit.state.wrapMessages.length,
      // shrinkWrap: true,
      reverse: false,
      itemBuilder: (BuildContext context, int index) {
        var wrapMessage = messageListCubit.state.wrapMessages.elementAt(index);
        return MessageItemView(wrapMessage: wrapMessage);
      },
    );
  }

  AppBar _buildAppBar(BuildContext context) {
    var arguments = ModalRoute.of(context)?.settings.arguments as Map;
    return AppBar(
      backgroundColor: Main_appbar_color,
      leading: GestureDetector(
          child: const Padding(
            padding: EdgeInsets.only(left: 0, right: 0),
            child: Icon(Icons.chevron_left, color: Main_appbar_text_color),
          ),
          onTap: () {
            ImSingleton.getInstance().cleanUiModel();
            Navigator.of(context).pop();
          }),
      titleSpacing: 5,
      title: Text(
        (arguments['name'] ?? ""),
        style: const TextStyle(color: Main_appbar_text_color, fontSize: ImConstant.IM_DEFAULT_SIZE),
      ),
      actions: [
        IconButton(
            icon: const Icon(
              Icons.more_horiz,
              color: Main_appbar_text_color,
            ),
            onPressed: () async {
              var sessionListCubit = context.read<SessionListCubit>();

              var sessionService = ImSessionService();
              var groupService = ImGroupService();
              var session = await sessionService.getById(widget.sessionId);
              if (session!.groupCode != null) {
                session!.group = await groupService.getByCodeAndUserId(session!.groupCode!, session!.currentUserId!);
              } else {
                session.toUser = await ImCacheFactory.getInstance().getImUser(session!.toUserId!);
              }

              Navigator.of(context).push(MaterialPageRoute(
                  builder: (BuildContext context) {
                    return BlocProvider(
                      create: (context) => SessionSettingCubit(session: session!, sessionListCubit: sessionListCubit),
                      child: _buildSettingPage(session!),
                    );
                  },
                  settings: const RouteSettings(name: '/MessageSendPage/Setting'))
              );
            }),
      ],
    );
  }

  Widget _buildSettingPage(ImSession session) {
    if (session!.groupCode == null) {
      return const SessionUserSettingPage();
    }
    return const SessionGroupSettingPage();
  }

  Widget _buildSendPane(MessageListCubit messageListCubit) {
    if (messageListCubit.state.selectable) {
      return const MessageHandlerView();
    } else {
      return const MessageSendCubitView();
    }
  }

  void _onScroll(MessageListCubit messageListCubit) {
    if (_scrollController.position.extentBefore > 0 || _scrollController.position.extentAfter > 0) {
      if (!isHaveScroll) {
        isHaveScroll = true;
      }
    } else {
      if (isHaveScroll) {
        isHaveScroll = false;
      }
    }


    if (isLoading) return;
    isLoading = true;
    if (_scrollController.position.pixels < 100 && isHaveScroll) {
      print('top load data!!!!!!!!!!!!!!!!');
      messageListCubit.add(MessageListLoadOldDataEvent(null));
    } else if (_scrollController.position.pixels > _scrollController.position.maxScrollExtent-100) {
      print('end load data!!!!!!!!!!!!!!!!');
      messageListCubit.add(MessageListLoadNewsDataEvent(null));
    }

    isLoading = false;
  }

  void _jumpToItem(int index, double alignment) {
    _listController.jumpToItem(
      index: index,
      scrollController: _scrollController,
      alignment: alignment,
    );
  }

  void _scroll(int selectIndex, bool isOld) async {
    if (isOld) {
      var isEnd = _jump(selectIndex, isOld);
      if(isEnd) return;
    }
    Future.microtask(() {
      WidgetsBinding.instance.addPostFrameCallback((_) async {
        var isEnd = _jump(selectIndex, isOld);
        int count = 0;
        while (!isEnd) {
          count++;
          if (count > 10) return;
          isEnd = await Future.delayed(const Duration(milliseconds: 300), (){
            return _jump(selectIndex, isOld);
          });
        }
        _logger.i("jump count: $count");
      });
    });
  }

  bool _jump(int selectIndex, bool isOld) {
    if (!_scrollController.hasClients) return false;
    ScrollPosition position = _scrollController.position;
    double endPosition = position.maxScrollExtent;
    if (position.pixels <= endPosition) {
      _jumpToItem(selectIndex, isOld ? 0 : 1);
      return true;
    }
    return false;
  }
}
